// ScriptCAPI.cpp: implementation of the CScriptCAPI class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <pgl/mfc/PGLCAPI.h>
#include <pgl/mfc/PGLScript.h>
#include <pgl/mfc/PGLDialog.h>
#include <pgl/mfc/PGLDialogList.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

namespace pgl
{
	namespace priv
	{
		static gfxinterface::CGDIpInitializer st_GDIpInitializer;
		static CString st_ScriptName(_T("PGLCAPI_Script"));
		static int st_bInitialized=false;
		static CPGLScriptPtr GetScript()
		{
			if (st_bInitialized)
				return CPGLScriptPoolSingleton::GetScript( st_ScriptName );
			else
				return CPGLScriptPtr();
		};
	}
};

int pglInit(int bInitGDIp, int bInitCOM)
{
	if (pgl::priv::st_bInitialized)
		return true;

	if (bInitCOM)
	{
		HRESULT hr=CoInitialize(NULL);
		if (FAILED(hr))
			return false;
	}

	if (bInitGDIp)
		pgl::priv::st_GDIpInitializer.Initialize();

	CPGLScriptPoolSingleton::CreateScript( pgl::priv::st_ScriptName );
	pgl::priv::st_bInitialized=true;

	return true;
};

int pglQuit(int bCloseCOM)
{
	if (!pgl::priv::st_bInitialized)
		return false;

	pgl::priv::st_GDIpInitializer.Deinitialize();

	if (bCloseCOM)
		CoUninitialize();

	CPGLScriptPoolSingleton::RemoveScript( pgl::priv::st_ScriptName );
	pgl::priv::st_bInitialized=false;

	return true;
};

long pglFigure()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Figure();
};

long pglRegion()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Region();
}

long pglGetCR()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetCR();
}

int pglSetCR( long dwRegionID)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->SetCR(dwRegionID);
}

long pglGetCD()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetCD();
}

void pglCloseFigure( long dwID)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->CloseFigure(dwID);
}

void pglCloseAllFigures()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->CloseAllFigures();
}
void pglCloseRegion( long dwID)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->CloseRegion(dwID);
}

void pglCloseAllRegions()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->CloseAllRegions();
}

long pglDivide(long lRegionID, long nRows, long nCols)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Divide(lRegionID, abs(nRows), abs(nCols));
}

long pglLayout(long lRegionID, LPCTSTR szLayout)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Layout(lRegionID, szLayout);
}

long pglGetObject( long lRegionID, long uIndex )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetObject(lRegionID, uIndex);
}

long pglGetObjectsSize( long lRegionID)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetObjectsSize(lRegionID);
}


long pglGetChild( long lRegionID, long uIndex )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetChild(lRegionID, uIndex);
}

long pglGetChildrenSize( long lRegionID )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetChildrenSize(lRegionID);
}

long pglGetParent(long uID )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->GetParent(uID);
}

long pglPlot(
    long lRegionID, 
    long nPoints, 
    float* pX, 
    float* pY, 
    LPCTSTR szFlags, 
    int makeCopy)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vX(new CPGLVectorF(pX,nPoints));
            CPGLVectorFPtr vY(new CPGLVectorF(pY,nPoints));
            return pScript->Plot(lRegionID, vX, vY, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vX(new CPGLCArrayF(pX,nPoints));
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY,nPoints));
            return pScript->Plot(lRegionID, vX, vY, szFlags);
        }
	}
}

long pglPlotHor(long lRegionID, float fY, LPCTSTR szFlags)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->PlotHor(lRegionID, fY, szFlags);
}

long pglPlotVer(long lRegionID, float fX, LPCTSTR szFlags)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->PlotVer(lRegionID, fX, szFlags);
}


long pglPlotFcn(
    long lRegionID, 
    long nPoints, 
    float* pX, 
    LPCTSTR szFcnX, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vX(new CPGLVectorF(pX,nPoints));
            return pScript->PlotFcn(lRegionID, vX, szFcnX, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vX(new CPGLCArrayF(pX,nPoints));
            return pScript->PlotFcn(lRegionID, vX, szFcnX, szFlags);
        }
	}
}

long pglPlotFcnY(long lRegionID, long nPoints, float fX0, float fXStep, LPCTSTR szFcnX, LPCTSTR szFlags)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
        return pScript->PlotFcnY(lRegionID, nPoints, fX0, fXStep, szFcnX, szFlags);
}

long pglPlotY(
    long lRegionID, 
    long nPoints, 
    float fX0, 
    float fXStep, 
    float* pY, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            return pScript->PlotY(lRegionID, 
                fX0, fXStep, 
                vY,
                szFlags);
        }
        else
        {
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY,nPoints));
            return pScript->PlotY(lRegionID, 
                fX0, fXStep, 
                vY,
                szFlags);
        }
    }
}

long pglPlotLOD(
    long lRegionID, 
    long nPoints, 
    float* pX, 
    float* pY, 
    float fCompressionRatio, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vX(new CPGLVectorF(pX, nPoints)); 
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints)); 
            return pScript->PlotLOD(lRegionID, 
                vX,
                vY,
                fCompressionRatio, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vX(new CPGLCArrayF(pX,nPoints));
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY,nPoints));
            return pScript->PlotLOD(lRegionID, 
                vX,
                vY,
                fCompressionRatio, szFlags);
        }
    }
}

long pglPlotLODY(
    long lRegionID, 
    long nPoints, 
    float fX0, 
    float fXStep, 
    float* pY, 
    float fCompressionRatio, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            return pScript->PlotLODY(lRegionID, 
                fX0, fXStep, 
                vY,
                fCompressionRatio, 
                szFlags);
        }
        else
        {
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY,nPoints));
            return pScript->PlotLODY(lRegionID, 
                fX0, fXStep, 
                vY,
                fCompressionRatio, 
                szFlags);
        }
	}
}

long pglHistogram(long lRegionID, long nPoints, float* pY, LPCTSTR szFlags, int makeCopy)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            return pScript->Histogram(lRegionID, vY, szFlags);
        }
        else
        {
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            return pScript->Histogram(lRegionID, vY, szFlags);
        }
	}
}

long pglErrorBar(
    long lRegionID, 
    long nPoints, 
    float* pX, 
    float* pY, 
    float* pErrorUp, 
    float* pErrorDown, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
    {
        if (makeCopy)
        {
            CPGLVectorFPtr vX(new CPGLVectorF(pX,nPoints));
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            CPGLVectorFPtr vEu(new CPGLVectorF(pErrorUp, nPoints));
            CPGLVectorFPtr vEd(new CPGLVectorF(pErrorDown, nPoints)); 
            return pScript->ErrorBar(lRegionID, vX,vY,vEu,vEd,szFlags);
        }
        else
        {
            CPGLCArrayFPtr vX(new CPGLCArrayF(pX,nPoints));
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY, nPoints));
            CPGLCArrayFPtr vEu(new CPGLCArrayF(pErrorUp, nPoints));
            CPGLCArrayFPtr vEd(new CPGLCArrayF(pErrorDown, nPoints)); 
            return pScript->ErrorBar(lRegionID, vX,vY,vEu,vEd,szFlags);
        }
    }
}

long pglErrorBarY(
    long lRegionID, 
    long nPoints, 
    float fX0, 
    float fXStep, 
    float* pY, 
    float* pErrorUp, 
    float* pErrorDown, 
    LPCTSTR szFlags,
    int makeCopy)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            CPGLVectorFPtr vEu(new CPGLVectorF(pErrorUp, nPoints));
            CPGLVectorFPtr vEd(new CPGLVectorF(pErrorDown, nPoints));
            return pScript->ErrorBarY(lRegionID, 
                fX0, fXStep, vY,vEu,vEd, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY, nPoints));
            CPGLCArrayFPtr vEu(new CPGLCArrayF(pErrorUp, nPoints));
            CPGLCArrayFPtr vEd(new CPGLCArrayF(pErrorDown, nPoints)); 
            return pScript->ErrorBarY(lRegionID, 
                fX0, fXStep, vY,vEu,vEd, szFlags);
        }
	}
}

long pglScatter(
    long lRegionID, 
    long nPoints, 
    float* pX, 
    float* pY, 
    float* pValues, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vX(new CPGLVectorF(pX, nPoints)); 
            CPGLVectorFPtr vY(new CPGLVectorF(pY, nPoints));
            CPGLVectorFPtr vValues(new CPGLVectorF(pValues, nPoints));
            return pScript->Scatter(lRegionID, vX,vY,vValues, szFlags);
       }
        else
        {
            CPGLCArrayFPtr vX(new CPGLCArrayF(pX, nPoints));
            CPGLCArrayFPtr vY(new CPGLCArrayF(pY, nPoints));
            CPGLCArrayFPtr vValues(new CPGLCArrayF(pValues, nPoints)); 
            return pScript->Scatter(lRegionID, vX,vY,vValues, szFlags);
        }
 	}
}

long pglStock(
    long lRegionID, 
    long nPoints, 
    float fX0, 
    float fXStep, 
    float* pOpen, 
    float* pHigh, 
    float* pLow, 
    float* pClose, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vOpen(new CPGLVectorF(pOpen, nPoints)); 
            CPGLVectorFPtr vHigh(new CPGLVectorF(pHigh, nPoints)); 
            CPGLVectorFPtr vLow(new CPGLVectorF(pLow, nPoints));
            CPGLVectorFPtr vClose(new CPGLVectorF(pClose, nPoints)); 
            return pScript->Stock(lRegionID, fX0, fXStep, vOpen,vHigh,vLow,vClose, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vOpen(new CPGLCArrayF(pOpen, nPoints)); 
            CPGLCArrayFPtr vHigh(new CPGLCArrayF(pHigh, nPoints)); 
            CPGLCArrayFPtr vLow(new CPGLCArrayF(pLow, nPoints));
            CPGLCArrayFPtr vClose(new CPGLCArrayF(pClose, nPoints)); 
            return pScript->Stock(lRegionID, fX0, fXStep, vOpen,vHigh,vLow,vClose, szFlags);
        }
	}
}

long pglCandleStick(
    long lRegionID, 
    long nPoints, 
    float fX0, 
    float fXStep, 
    float* pOpen, 
    float* pHigh, 
    float* pLow, 
    float* pClose, 
    LPCTSTR szFlags,
    int makeCopy
    )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
	{
        if (makeCopy)
        {
            CPGLVectorFPtr vOpen(new CPGLVectorF(pOpen, nPoints)); 
            CPGLVectorFPtr vHigh(new CPGLVectorF(pHigh, nPoints)); 
            CPGLVectorFPtr vLow(new CPGLVectorF(pLow, nPoints));
            CPGLVectorFPtr vClose(new CPGLVectorF(pClose, nPoints)); 
            return pScript->CandleStick(lRegionID, fX0, fXStep, vOpen,vHigh,vLow,vClose, szFlags);
        }
        else
        {
            CPGLCArrayFPtr vOpen(new CPGLCArrayF(pOpen, nPoints)); 
            CPGLCArrayFPtr vHigh(new CPGLCArrayF(pHigh, nPoints)); 
            CPGLCArrayFPtr vLow(new CPGLCArrayF(pLow, nPoints));
            CPGLCArrayFPtr vClose(new CPGLCArrayF(pClose, nPoints)); 
            return pScript->CandleStick(lRegionID, fX0, fXStep, vOpen,vHigh,vLow,vClose, szFlags);
        }
	}
}

long pglLegend(long lRegionID)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Legend(lRegionID);
}

long pglLeftLabel(long lRegionID, LPCTSTR szLabel)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->LeftLabel(lRegionID, szLabel);
}

long pglBottomLabel(long lRegionID, LPCTSTR szLabel)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->BottomLabel(lRegionID, szLabel);
}
long pglTitle(long lRegionID, LPCTSTR szLabel)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->Title(lRegionID, szLabel);
}
long pglRightLabel(long lRegionID, LPCTSTR szLabel)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->RightLabel(lRegionID, szLabel);
}


void pglAutoZoom(LPCTSTR szState )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->AutoZoom(szState);
}

long pglLoadFromXML(long lRegionID, LPCTSTR szFileName )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->LoadFromXML(lRegionID, szFileName);
}

int pglLoadCSVFile( long lRegionID, LPCTSTR szFileName)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->LoadCSVFile(lRegionID, szFileName);	
}


int pglSaveToXML(long lRegionID, LPCTSTR szFileName, int bZipping )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;
	else
		return pScript->SaveToXML(lRegionID, szFileName, bZipping);
}

int pglRenderToFile(long lRegionID, LPCTSTR szFileName, LPCTSTR szFormat )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;
	else
		return pScript->RenderToFile(lRegionID, szFileName, szFormat);
}

int pglRenderToBitmap(
	long lRegionID, 
	unsigned int width_,
	unsigned int height_,
	unsigned int stride_,
	unsigned int bpp_,
	char* bits_,
    LPCTSTR szFlags_
	)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;
	else
		return pScript->RenderToBitmap(
			lRegionID, 
			width_,
			height_,
			stride_,
			bpp_,
			bits_,
            szFlags_
            );
};


long pglImage(long lRegionID, LPCTSTR szFileName, LPCTSTR szFlags)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;
	else
		return pScript->Image(lRegionID, szFileName, szFlags);
}

void pglRemoveChild( long lRegionID, long uIndex )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->RemoveChild(lRegionID, uIndex);
}

void pglRemoveObject( long lRegionID, long uIndex )
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->RemoveObject(lRegionID, uIndex);
}

void pglZoomAll(long lRegionID, int bRecurse)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->ZoomAll(lRegionID, bRecurse);
}

void pglZoom(long lRegionID, double dLeft, double dBottom, double dRight, double dTop)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	else
		pScript->Zoom(lRegionID, CPGLRectD(dLeft, dBottom, dRight, dTop));
}

int	 pglGetZoom(long lRegionID, double* pLeft, double* pTop, double* pRight, double* pBottom)
{
	if (!pLeft || !pTop || !pRight || !pBottom)
		return false;

	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;
	
	CPGLRectD r;		
	if (!pScript->GetZoom(lRegionID, r))		
		return false;

	*pLeft=r.left;
	*pTop=r.top;
	*pRight=r.right;
	*pBottom=r.bottom;

	return true;
}

long pglOutOfChild()
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return 0;
	else
		return pScript->OutOfChild();
}

void pglSet(long uObjectID, LPCTSTR szPropAndValues)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return ;
	
	pScript->Set(uObjectID, szPropAndValues);	
}

void pglGet(long uObjectID, LPCTSTR szProperty, TCHAR** ppStr)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;
	
	CString str;
	pScript->Get(uObjectID, szProperty, str);
	if (!str.IsEmpty())
	{
		// allocating memory for the string...
		*ppStr = new TCHAR[ str.GetLength()+1];
		_tcscpy( *ppStr, str);
	}
}

void pglGetHelp(long uObjectID, TCHAR** ppStr)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return;

	CString str;
	pScript->GetHelp(uObjectID, str);
	if (!str.IsEmpty())
	{
		// allocating memory for the string...
		*ppStr = new TCHAR[ str.GetLength()+1];
		_tcscpy( *ppStr, str);
	}	
}

int pglDoModalRegion(long lRegionID, LPCTSTR szFlags)
{
	CPGLScriptPtr pScript=pgl::priv::GetScript();
	if (!pScript)
		return false;

	DWORD dwFlags=0;
	while(_tcslen(szFlags))
	{
		switch(szFlags[0]) 
		{
		case 'a':
			dwFlags|=CPGLDialog::OptionNoZoomAll;
			break;
		case 't':
			dwFlags|=CPGLDialog::OptionTripleBuffering;
			break;
		case 'o':
			dwFlags|=CPGLDialog::OptionNoToolBar;
			break;
		case 'k':
			dwFlags|=CPGLDialog::OptionNoTaskBar;
			break;
		case 'm':
			dwFlags|=CPGLDialog::OptionClipboardMetafile;
			break;
		}

		szFlags=_tcsinc(szFlags);
	}

	return pScript->DoModalRegion(lRegionID,dwFlags);
}
